package com.dingding.service.userorderservice.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.bean.databean.push.AuroraPushBean;
import com.dingding.bean.databean.push.LongDistanceConfig;
import com.dingding.bean.databean.push.PushAutomaticCancelOrder;
import com.dingding.bean.databean.push.PushCompetitiveOrder;
import com.dingding.bean.databean.push.PushConfig;
import com.dingding.bean.databean.push.PushData;
import com.dingding.bean.databean.request.ReqCalculateDistance;
import com.dingding.bean.databean.request.ReqCompetitiveOrder;
import com.dingding.bean.databean.request.ReqGetMapShowRoute;
import com.dingding.bean.databean.request.ReqGetNearbyOrderList;
import com.dingding.bean.databean.request.ReqGetNearbyUserList;
import com.dingding.bean.databean.request.ReqGetOrderInfo;
import com.dingding.bean.databean.request.ReqGoToPay;
import com.dingding.bean.databean.request.ReqPublishAboutCar;
import com.dingding.bean.databean.request.ReqUserLocation;
import com.dingding.bean.databean.response.Coupon;
import com.dingding.bean.databean.response.DataResponse;
import com.dingding.bean.databean.response.NearbyOrderList;
import com.dingding.bean.databean.response.ResCalculateDistance;
import com.dingding.bean.databean.response.ResCompetitiveOrder;
import com.dingding.bean.databean.response.ResCoupon;
import com.dingding.bean.databean.response.ResGetMapShowRoute;
import com.dingding.bean.databean.response.ResGetNearbyUserList;
import com.dingding.bean.databean.response.ResGetOrderInfo;
import com.dingding.bean.databean.response.ResGetUserWallet;
import com.dingding.bean.databean.response.ResGoToPay;
import com.dingding.bean.databean.response.ResNearbyUserInfo;
import com.dingding.bean.databean.response.ResPublishAboutCar;
import com.dingding.bean.entity.Stageprice;
import com.dingding.bean.entity.UserLocation;
import com.dingding.bean.entity.UserLogin;
import com.dingding.bean.entity.Userdetail;
import com.dingding.bean.entity.Userorder;
import com.dingding.cache.ordercache.OrderCache;
import com.dingding.cache.ordercache.OrderPushCache;
import com.dingding.common.core.beans.UserCoupon;
import com.dingding.common.core.beans.Userordert;
import com.dingding.common.core.config.ServiceCode;
import com.dingding.common.core.config.SystemCode;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.GetDistanceUtil;
import com.dingding.common.core.util.JSONUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.dto.CalculatDistanceDTO;
import com.dingding.dao.sql.UserOrderDaoSql;
import com.dingding.facade.queue.dto.msg.MessageRequestsDTO;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.facde.activity.enums.AttendActivityEnum;
import com.dingding.message.MessageModel;
import com.dingding.message.PushModel;
import com.dingding.service.BaseService;
import com.dingding.service.userorderservice.IUserOrderTService;
import com.dingding.util.OrderPriceUtil;
import com.dingding.util.SendPushUtil;

/**
 * 
 * @ClassName: UserOrderTServiceImpl
 * @Description:用户订单临时service实现
 * @author cheshaowei
 * @date 2015-10-21 上午10:43:50
 */
@SuppressWarnings("all")
public class UserOrderTServiceImpl extends BaseService implements IUserOrderTService {

	private static final Logger log = Logger.getLogger(UserOrderTServiceImpl.class);
	
	@Resource(name = "queueFacade")
	private IQueueFacade queuefacade;

	/**
	 * @throws ParseException
	 * @Title: publishAboutCar
	 * @Description:发布订单
	 * @param reqPublishAboutCar 客户端请求数据封装bean
	 * @author cheshaowei
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void publishAboutCar(ReqPublishAboutCar reqPublishAboutCar, DataResponse dataResponse) {

		// 验证是否能下单 true:验证通过 false:不符合下单条件
		boolean flag = this.isValidateParamTrue(reqPublishAboutCar, dataResponse);

		if (!flag) {
			return;
		}

		// 获取订单类型 1:普通 2:长途
		int isLongDistance = this.getLongDistance(reqPublishAboutCar);

		Userordert userordert = new Userordert();
		// 将客户端请求数据bean转换成数据库保存bean
		super.userOrderTDao.convertBean(reqPublishAboutCar, userordert);

		// 时间戳+6位随机数
		String oid = DateFormatUtil.getTimeInMillis().toString() + ToolUtil.generateCellPhoneValNum();
		// 订单ID
		userordert.setOid(oid);
		// 订单状态 1：待抢单
		userordert.setOrderStatus(1);
		// 下单时间
		userordert.setCreateTime(new Date());
		// 订单类型 1：普通 2:长途
		userordert.setIsLongDistance(isLongDistance);

		// 如果用户为乘客，则在订单信息中添加用户优惠Id和优惠金额
		if (reqPublishAboutCar.getUserType() == 2) {

			if (ToolUtil.isNotBlank(reqPublishAboutCar.getUcid()) && reqPublishAboutCar.getCouponMoney() != null) {

				userordert.setUcId(reqPublishAboutCar.getUcid());// 用户优惠券Id
				userordert.setCouponMoney(reqPublishAboutCar.getCouponMoney());// 优惠金额

				// 设置获取优惠券信息的查询条件
				Criterion criterion = Restrictions.eq("ucId", reqPublishAboutCar.getUcid());

				// 根据优惠券Id获取优惠券信息
				UserCoupon userCoupon = null;
				try {
					userCoupon = super.userCouponDao.queryCriteriaUnResult(criterion, false);
				} catch (Exception e) {
					log.error("根据用户优惠券Id获取优惠券信息是出现异常 类：" + this.getClass(), e);
					setStatus(dataResponse, SystemCode.ERROR);
					return;
				}

				if (userCoupon != null) {
					// 修改优惠券状态为已使用
					userCoupon.setCouponStatus(3);
				}
			}
		}

		// 判断优惠金额是否为空
		if (userordert.getCouponMoney() == null) {
			userordert.setCouponMoney(new BigDecimal(0));
		}

		try {
			// 保存数据到数据库
			super.userOrderTDao.save(userordert);
		} catch (Exception e) {
			log.error("发布订单出现异常！类：" + this.getClass() + " 方法：publishAboutCar()", e);
			setStatus(dataResponse, SystemCode.ERROR);
			return;
		}

		// 顺路推送
		// pushToCurrentUsers(reqPublishAboutCar, userordert);

		// 添加数据到缓存中
		OrderCache orderCache = new OrderCache();
		boolean isAddSucc = orderCache.publishAboutCar(oid);
		if (!isAddSucc) {
			log.error("下单添加订单到缓存中失败！订单ID为：" + oid);
		}

		// 创建响应数据bean
		ResPublishAboutCar resPublishAboutCar = new ResPublishAboutCar();
		// 订单ID
		resPublishAboutCar.setOid(oid);
		// 创建订单时间
		resPublishAboutCar.setOrderCreateTime(userordert.getCreateTime());
		// 1:普通 2:长途
		resPublishAboutCar.setIsLongDistance(userordert.getIsLongDistance());

		// 设置数据响应体
		dataResponse.setResponseBody(resPublishAboutCar);
		setStatus(dataResponse, SystemCode.SUCCESS);

	}

	/**
	 * @Title: getLongDistance
	 * @Description: 获取订单类型  1:普通  2:长途
	 * @param reqPublishAboutCar
	 * @author yuHaiQing
	 * @return int    返回类型
	 * @throws
	 */
	public int getLongDistance(ReqPublishAboutCar reqPublishAboutCar) {

		// 根据客户端参数设置的短长途类型,默认为普通
		int isLongDistance = 1;

		// 区分短长途的条件
		LongDistanceConfig longDistanceConfig = OrderCache.longDistanceConfig();

		// 判断是否为长途类型
		if (reqPublishAboutCar.getDistance().compareTo(longDistanceConfig.getLongDistance()) > 0) {
			isLongDistance = 2;
		}

		return isLongDistance;
	}

	/**
	 * @Title: pushToCurrentUsers
	 * @Description: 同城推送
	 * @param userordert
	 *            订单的内容
	 * @author lijinchao
	 * @throws ParseException
	 */
	private void pushToCurrentUsers(ReqPublishAboutCar reqPublishAboutCar, Userordert userordert) {

		List<AuroraPushBean> auroraPushBeans = null;

		// 订单推送匹配条件
		PushConfig pushConfig = OrderPushCache.orderPushIntital();

		if (pushConfig.getIsEnableOrderPush() == 1) {

			// 获取符合条件的用户列表
			List<Object[]> objects = null;
			try {
				// 获取符合条件的用户列表
				objects = super.userOrderDao.sqlQueryListObj(
						UserOrderDaoSql.GET_PUSH_USER_INFO(reqPublishAboutCar.getUserType()), false,
						userordert.getPlaceOrderUserId());
			} catch (Exception e) {
				log.error("用户下单推送，获取符合条件的用户列表时出现异常   类：" + this.getClass() + " pushToCurrentUsers()", e);
			}

			// 查询当前发布订单人的信息
			Criterion criterion = Restrictions.eq("loginId", userordert.getPlaceOrderUserId());
			// 创建用户详情对象
			Userdetail userdetail = null;
			try {
				userdetail = super.userDetailDao.queryCriteriaUnResult(criterion, false);
			} catch (Exception e) {
				log.error("同城推送时根据发单人的用户id查询用户信息出现异常" + this.getClass() + " 方法名：publishAboutCar()", e);
			}

			if (objects != null && objects.size() > 0 && userdetail != null) {
				// 获取推送时所需条件
				auroraPushBeans = this.getAuroraPushBeans(objects, userordert, userdetail, pushConfig);
			}
		}

		if (auroraPushBeans != null && auroraPushBeans.size() > 0) {

			// 用户下单推送，自定义参数
			Map<String, String> map = new HashMap<String, String>();

			map.put("oid", userordert.getOid()); // 订单Id
			map.put("orderType", userordert.getOrderType().toString());// 下单类型(1:乘客下单
																		// 2:司机下单)
			map.put("modular", ServiceCode.CURRENTCITY_PUSH); // modular(接口名)

			// 遍历推送订单信息给用户
			for (AuroraPushBean auroraPushBean : auroraPushBeans) {

				SendPushUtil.sendPushCustomParam(auroraPushBean.getAliasId(), auroraPushBean.getAlert(),
						auroraPushBean.getMsgTitle(), auroraPushBean.getMsgContent(), auroraPushBean.getClientType(),
						map);

			}
		}
	}

	/**
	 * @Title: getAuroraPushBeans @Description: 获取推送信息 @param objects
	 * 获取到的用户信息列表 @param userordert 订单详情 @param userdetail 下单用户详情 @author
	 * yuHaiQing @return List<AuroraPushBean> 返回类型 @throws
	 */
	public List<AuroraPushBean> getAuroraPushBeans(List<Object[]> objects, Userordert userordert, Userdetail userdetail,
			PushConfig pushConfig) {

		// 创建存储推送信息列表
		List<AuroraPushBean> auroraPushBeans = new ArrayList<AuroraPushBean>();

		// 去重(去除重复出现的用户)
		this.duplicateRemoval(objects);

		for (Object[] obj : objects) {

			// 验证推送用户信息是否为空
			boolean flag = this.validatePushUserList(obj);

			if (!flag) {
				continue;
			}

			double orderStartLongitude = userordert.getStartLongitude();// 订单起点经度
			double orderStartLatitude = userordert.getStartLatitude();// 订单起点纬度
			double orderEndLongitude = userordert.getEndLongitude();// 订单终点经度
			double orderEndLatitude = userordert.getEndLatitude();// 订单终点纬度
			double userStartLongitude = 0;// 用户起点经度
			if (obj[1] != null) {
				userStartLongitude = ToolUtil.castDouble(obj[1]);
			}
			double userStartLatitude = 0;// 用户起点纬度
			if (obj[2] != null) {
				userStartLatitude = ToolUtil.castDouble(obj[2]);
			}
			double userEndLongitude = 0;// 用户终点经度
			if (obj[3] != null) {
				userEndLongitude = ToolUtil.castDouble(obj[3]);
			}
			double userEndLatitude = 0;// 用户终点纬度
			if (obj[4] != null) {
				userEndLatitude = ToolUtil.castDouble(obj[4]);
			}
			Date orderSetOutTime = userordert.getSetOutTime();// 订单出发时间
			Date userSetOutTime = null;// 用户路线出发时间
			if (obj[0] != null) {
				userSetOutTime = (Date) obj[0];
			}

			// 订单起点跟用户路线起点的距离
			BigDecimal startRange = GetDistanceUtil.GetDistance(orderStartLongitude, orderStartLatitude, userStartLongitude,
					userStartLatitude);
			// 订单终点跟用户路线终点的距离
			BigDecimal endRange = GetDistanceUtil.GetDistance(orderEndLongitude, orderEndLatitude, userEndLongitude,
					userEndLatitude);
			// 订单出发时间跟用户路线出发时间的时间间隔
			long timeRange = 0;
			try {
				timeRange = DateFormatUtil.getTimeIntervalS(userSetOutTime, orderSetOutTime);
			} catch (Exception e) {
				log.error("用户下单推送时，计算两时间点的时间间隔出现异常   类：" + this.getClass() + " getAuroraPushBeans()", e);
				continue;
			}

			// 获取极光推送Bean
			AuroraPushBean auroraPushBean = this.getAuroraPushBean(obj, startRange.doubleValue(), endRange.doubleValue(), timeRange, pushConfig,
					userordert, userdetail);

			if (auroraPushBean != null && ToolUtil.isNotBlank(auroraPushBean.getAliasId())) {
				auroraPushBeans.add(auroraPushBean);
			}

		}

		return auroraPushBeans;
	}

	/**
	 * @Title: validatePushUserList
	 * @Description: 验证推送用户信息
	 * @param obj
	 *            推送用户信息
	 * @author yuHaiQing
	 * @return boolean 返回类型
	 */
	public boolean validatePushUserList(Object[] obj) {

		// 判断如果用户的起点、终点和出发时间如果为空，则跳过本次循环，进入下次循环
		if (obj[0] == null // 出发时间
				&& obj[1] == null // 起点经度
				&& obj[2] == null // 起点纬度
				&& obj[3] == null // 终点经度
				&& obj[4] == null // 终点纬度
				&& obj[7] == null // 订单提醒(1:开启 2:关闭)
				&& obj[8] == null // 周末推送(1:开启 2:关闭)
				&& obj[9] == null) {// 推送条件(1:非常顺路 2:标准顺路 3：一般顺路)
			return false;
		}

		return true;
	}

	/**
	 * @Title: duplicateRemoval @Description: 去重 @author yuHaiQing @return void
	 * 返回类型 @throws
	 */
	public void duplicateRemoval(List<Object[]> objects) {

		// 去重(去除集合中重复的用户信息)
		for (int i = 0; i < objects.size(); i++) {// 外循环是循环的次数

			for (int j = objects.size() - 1; j > i; j--) {// 内循环是 外循环一次比较的次数

				// 判断中别名是否有重复的，如果有，则移除。
				if (objects.get(i) != null && objects.get(j) != null && objects.get(i)[5] != null
						&& objects.get(j)[5] != null && objects.get(i)[5] == objects.get(j)[5]) {
					objects.remove(j);// 移除重复的用户
				}
			}
		}
	}

	/**
	 * @Title: getAuroraPushBean
	 * @Description: 获取推送所需Bean
	 * @param obj
	 *            推送用户Bean
	 * @param startRange
	 *            起点范围
	 * @param endRange
	 *            终点范围
	 * @param timeRange
	 *            出发时间间隔
	 * @param pushConfig
	 *            订单推送匹配条件
	 * @author yuHaiQing
	 * @return AuroraPushBean 返回类型
	 */
	public AuroraPushBean getAuroraPushBean(Object[] obj, double startRange, double endRange, long timeRange,
			PushConfig pushConfig, Userordert userordert, Userdetail userdetail) {

		// 创建推送信息对象
		AuroraPushBean auroraPushBean = new AuroraPushBean();

		Integer orderReminder = null;// 订单提醒(1:开启 2:关闭)
		if (obj[7] != null) {
			orderReminder = ToolUtil.castInteger(obj[7]);
		}
		Integer weekendPush = null;// 周末推送(1:开启 2:关闭)
		if (obj[8] != null) {
			weekendPush = ToolUtil.castInteger(obj[8]);
		}
		Integer regularRouteConditions = null;// 推送条件(1:非常顺路 2:标准顺路 3：一般顺路)
		if (obj[9] != null) {
			regularRouteConditions = ToolUtil.castInteger(obj[9]);
		}

		// 判断订单出发时间是否为周六日 true:是周末 false:不是周末
		boolean flag = DateFormatUtil.isWeekend(userordert.getSetOutTime());

		// 判断推送的时间段
		if (orderReminder == 1 && weekendPush == 2) {// 周六日不推送
			if (flag) {
				return null;
			}
		} else if (orderReminder == 2 && weekendPush == 1) {// 只在周六日推送
			if (!flag) {
				return null;
			}
		}

		double startRule = 0; // 起点范围
		double endRule = 0; // 终点范围
		long timeRule = 0; // 出发时间范围

		if (regularRouteConditions == 1) { // 非常顺路
			startRule = pushConfig.getStartDistance();
			endRule = pushConfig.getEndDistance();
			timeRule = pushConfig.getStartTime();
		} else if (regularRouteConditions == 2) {// 标准
			startRule = pushConfig.getStartDistance_standard();
			endRule = pushConfig.getEndDistance_standard();
			timeRule = pushConfig.getStartTime_standard();
		} else if (regularRouteConditions == 3) {// 一般顺路
			startRule = pushConfig.getStartDistance_ordinary();
			endRule = pushConfig.getEndDistance_ordinary();
			timeRule = pushConfig.getStartTime_ordinary();
		}

		// 判断获取到的用户列表是否符合推送条件
		if (startRange <= startRule && endRange <= endRule && timeRange <= timeRule) {

			// 推送别名
			auroraPushBean.setAliasId(obj[5].toString());

			if (obj[6] != null && obj[6].toString().equals("1")) {
				// 设备类型
				auroraPushBean.setClientType("iOS");
			} else if (obj[6] != null && obj[6].toString().equals("2")) {
				// 设备类型
				auroraPushBean.setClientType("Android");
			}

			// 推送内容
			String msgContent = this.getPushData(userdetail, userordert, ServiceCode.CURRENTCITY_PUSH);

			// 通知标题
			String title = "";

			if ("非常顺路".equals("")) {
				title += "[非常顺路]";
			} else if ("一般顺路".equals("")) {
				title += "[一般顺路]";
			}

			title = this.setTitle(title, userdetail, userordert);
			// 自定义标题
			auroraPushBean.setMsgTitle(title);
			// 通知标题
			auroraPushBean.setAlert(title);
			// 推送内容
			auroraPushBean.setMsgContent(msgContent);

		}

		return auroraPushBean;
	}

	/**
	 * 同城推送，设置推送标题
	 */
	public String setTitle(String alert, Userdetail userdetail, Userordert userordert) {

		// 获取出发时间字符串
		String dateStr = this.getDateStr(userordert.getSetOutTime());

		// 乘客发单
		if (userordert.getOrderType() == 1) {
			alert += dateStr + "，乘客" + userdetail.getNickName();
		} else {
			alert += dateStr + "，车主" + userdetail.getNickName();
		}

		if (userdetail.getSex() == 1) {
			alert += "先生";
		} else {
			alert += "女士";
		}

		alert += "，从" + userordert.getStartAddress() + "到" + userordert.getEndAddress();

		return alert;
	}

	// 判断出发时间是否为今天，并返回时间字符串
	public String getDateStr(Date setOutTime) {

		StringBuilder dateStr = new StringBuilder();

		// 判断时间段
		Calendar calendarSetOutTime = Calendar.getInstance();

		// 将订单的出发时间赋给calendarSetOutTime
		calendarSetOutTime.setTime(setOutTime);

		// 系统当前时间
		Calendar calendarCurrent = Calendar.getInstance();

		// 设置时间格式
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd");

		// 获取出发时间的年月日
		String setOutTimeDate = sdf.format(calendarSetOutTime.getTime());

		// 获取当前时间的年月日
		String currentDate = sdf.format(calendarCurrent.getTime());

		dateStr.append("[同城推送]");

		// 判断出发日期是否为当日
		if (setOutTimeDate.equals(currentDate)) {
			dateStr.append("今天 ");
		} else {
			dateStr.append(new SimpleDateFormat("MM月dd日").format(calendarSetOutTime.getTime()));
		}

		dateStr.append(new SimpleDateFormat("HH : mm").format(calendarSetOutTime.getTime()));

		return dateStr.toString();
	}

	/**
	 * @Title: validateParamIsNull @Description: 验证传入参数是否为空 @param
	 *         reqPublishAboutCar 用户抢单-客户端请求参数 @return boolean 返回类型 true:验证通过
	 *         false:传入参数为空 @throws
	 */
	public boolean isValidateParamTrue(ReqPublishAboutCar reqPublishAboutCar, DataResponse dataResponse) {

		if (reqPublishAboutCar == null // 客户端传入参数是否为空
				|| reqPublishAboutCar.getUserType() == null // 当前用户角色
				|| ToolUtil.isBlank(reqPublishAboutCar.getPlaceOrderUserId()) // 下单用户Id是否为空
				|| ToolUtil.isBlank(reqPublishAboutCar.getPayCity()) // 下单城市是否为空
				|| reqPublishAboutCar.getSetOutTime() == null // 出发时间是否为空
				|| ToolUtil.isBlank(reqPublishAboutCar.getStartAddress()) // 出发地是否为空
				|| reqPublishAboutCar.getStartLongitude() == null // 起点经度是否为空
				|| reqPublishAboutCar.getStartLatitude() == null // 起点纬度是否为空
				|| ToolUtil.isBlank(reqPublishAboutCar.getEndAddress()) // 目的地是否为空
				|| reqPublishAboutCar.getEndLongitude() == null // 目的地经度是否为空
				|| reqPublishAboutCar.getEndLatitude() == null // 目的地纬度是否为空
				|| reqPublishAboutCar.getDistance() == null // 距离是否为空
				|| reqPublishAboutCar.getTotalMoney() == null // 总金额是否为空
				|| reqPublishAboutCar.getNumber() == null // 人数是否为空
		) { // 留言是否为空
			// 客户端传入参数为空
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return false;
		}

		/*
		 * if(reqPublishAboutCar.getUserType() == 2){
		 * if(ToolUtil.isBlank(reqPublishAboutCar.getUcid()) ||
		 * reqPublishAboutCar.getCouponMoney() == null){ //客户端传入参数为空
		 * setStatus(dataResponse, SystemCode.DATA_NULL_ERROR); return false; }
		 * }
		 */

		// 客户端传的时间如果是不正确的
		if (DateFormatUtil.isClientTimeNotTrue(reqPublishAboutCar.getSetOutTime())) {
			// 客户端传入时间格式不正确
			setStatus(dataResponse, SystemCode.SET_OUT_TIME_ERROR);
			return false;
		}

		// 发布者ID
		String userId = reqPublishAboutCar.getPlaceOrderUserId();

		// 判断该用户是否存在未完成订单
		List<Userordert> userorderts = this.existNotCompleteOrder(userId);

		if (userorderts == null) {
			userorderts = new ArrayList<Userordert>();
		}

		// 判断未完成订单量是否达到上限
		if (userorderts.size() >= 2) {
			setStatus(dataResponse, SystemCode.USER_ORDERT_TOO_MANY_ERROR);// 未完成订单达到上限
			return false;
		}

		// 获取订单类型 1:普通 2:长途
		int isLongDistance = this.getLongDistance(reqPublishAboutCar);

		if (userorderts.size() == 1) {
			// 下单类型与已存在类型是否相同
			if (userorderts.get(0).getIsLongDistance() == isLongDistance) {
				if (isLongDistance == 1) {
					setStatus(dataResponse, SystemCode.USER_ORDERT_NOT_SAME_SHORT_ERROR);// 不能同时存在两个短途单
				} else {
					setStatus(dataResponse, SystemCode.USER_ORDERT_NOT_SAME_LONG_ERROR);// 不能同时存在两种长途单
				}
				return false;
			}
		}

		// 判断当前用户的发单及抢单次数有没有超过5次
		UserLogin userLogin = super.userLoginService.getUserLoginInfo(userId, dataResponse);

		if (userLogin == null) {
			return false;
		}

		// // 获取当前用户的取消次数
		// int cancelNumber = userLogin.getCancelNumber();
		// // 获取当前用户的下单次数，如果超过5不能接单
		// int publishNumber = userLogin.getPublishNumber();
		//
		// // 当天取消超过3次
		// if (cancelNumber >= 3) {
		// setStatus(dataResponse, SystemCode.CANCEL_ORDER_TOO_MUCH);
		// return false;
		// }
		// // 当日接单超过5次
		// if (publishNumber >= 5) {
		// setStatus(dataResponse, SystemCode.PUBLISH_ORDER_TOO_MUCH);
		// return false;
		// }

		return true;
	}

	/**
	 * @Title: competitiveOrder 
	 * @Description:用户抢单 
	 * @author cheshaowei 
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void competitiveOrder(ReqCompetitiveOrder reqCompetitiveOrder, DataResponse dataResponse) {

		// 验证用户抢单时客户端请求参数是否为空
		boolean isTrue = this.isValidateCompetitiveOrderParamTrue(reqCompetitiveOrder);

		if (!isTrue) { // 订单是否为空
			log.error("抢单参数存在空值");
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return;
		}

		// 创建存储该抢单用户的优惠券信息对象
		UserCoupon userCoupon = null;

		// 如果抢单用户为乘客
		if (reqCompetitiveOrder.getUserType() == 2 && ToolUtil.isNotBlank(reqCompetitiveOrder.getUcId())) {
			// 设置获取优惠券信息的查询条件
			Criterion criterion = Restrictions.eq("ucId", reqCompetitiveOrder.getUcId());

			try {
				// 根据优惠券Id获取优惠券信息
				userCoupon = super.userCouponDao.queryCriteriaUnResult(criterion, false);

			} catch (Exception e) {
				log.error("修改优惠券状态时出现异常  类：" + this.getClass() + " competitiveOrder()", e);
				setStatus(dataResponse, SystemCode.ERROR);
				return;
			}
		}

		// 执行抢单,更改订单状态
		Userordert userordert = getOrderStatus(reqCompetitiveOrder, dataResponse);
		// 发送短信及消息推送
		if (userordert != null) {

			if (userCoupon != null) {
				// 修改优惠券状态为已使用
				userCoupon.setCouponStatus(3);
			}

			// 获取当前订单的下单用户ID
			String userId = null;
			if (ToolUtil.isNotBlank(userordert.getPlaceOrderUserId())) {
				userId = userordert.getPlaceOrderUserId();
			}
			// 根据用户ID获取用户详细信息及车主信息
			int userType = reqCompetitiveOrder.getUserType();
			// 抢单用户Id
			String grabOrderUserId = reqCompetitiveOrder.getGrabOrderUserId();

			// 获取下单用户电话以及推送内容
			PushCompetitiveOrder pushCompetitiveOrder = super.userDetailDao.getUserInfo(userType, userId,
					grabOrderUserId);

			// 订单Id
			if (ToolUtil.isNotBlank(userordert.getOid())) {
				pushCompetitiveOrder.setOid(userordert.getOid());
			}
			// 抢单时间
			if (userordert.getGrabOrderTime() != null) {
				pushCompetitiveOrder.setGrabOrderTime(userordert.getGrabOrderTime());
			}
			// 抢单用户Id
			if (ToolUtil.isNotBlank(userordert.getGrabOrderUserId())) {
				pushCompetitiveOrder.setGrabOrderUserId(userordert.getGrabOrderUserId());
			}
			// 订单状态
			if (userordert.getOrderStatus() != null) {
				pushCompetitiveOrder.setOrderStatus(userordert.getOrderStatus());
			}

			// 发送短信
			this.sendMessage(reqCompetitiveOrder, pushCompetitiveOrder);

			// 推送消息
			this.sendPush(reqCompetitiveOrder, pushCompetitiveOrder, ServiceCode.COMPETITIVE_ORDER_PUSH);

			// 发送邮件
			// this.sendEmail(pushCompetitiveOrder,userordert);

			// 创建响应对象
			ResCompetitiveOrder resCompetitiveOrder = new ResCompetitiveOrder();
			// 抢单时间
			if (userordert.getGrabOrderTime() != null) {
				resCompetitiveOrder.setGrabOrderTime(userordert.getGrabOrderTime());
			}
			// 乘客抢单时，向抢单乘客响应 车主的信息
			if (userType == 2) { // 1：车主 2：乘客

				resCompetitiveOrder = super.userOrderTDao.getResCompetitiveOrderDetail(resCompetitiveOrder, userId);
			}

			// 将响应Bean赋值给DataResponse
			dataResponse.setResponseBody(resCompetitiveOrder);

			setStatus(dataResponse, SystemCode.SUCCESS);

		}

	}

	/**
	 * @Title: getOrderCacheStatus @Description: 获取订单状态 @param
	 *         reqCompetitiveOrder @param dataResponse @return @author
	 *         lijinchao @return boolean @throws
	 */
	private synchronized boolean getOrderCacheStatus(ReqCompetitiveOrder reqCompetitiveOrder,
			DataResponse dataResponse) {
		// 从缓存中获取订单状态
		OrderCache orderCache = new OrderCache();
		// 从缓存中获取订单状态
		String orderCacheId = orderCache.getOrderStatus(reqCompetitiveOrder.getOid());
		if (orderCacheId != null && !orderCacheId.equals("1")) { // 缓存中的订单为不是待抢单状态
			return false;
		} else { // 设置缓存中的订单为已抢单
			// 设置缓存
			OrderCache cache = new OrderCache();
			// 已抢单 2：已抢单
			cache.setOrderStatus(reqCompetitiveOrder.getOid(), "2");
			return true;
		}
	}

	/**
	 * @Title: validateCompetitiveOrderParam @Description:
	 *         验证用户抢单时客户端传入参数是否为空 @param reqCompetitiveOrder 客户端请求参数 @return
	 *         true 参数正确 false 参数错误 @throws
	 */
	private boolean isValidateCompetitiveOrderParamTrue(ReqCompetitiveOrder reqCompetitiveOrder) {

		if (reqCompetitiveOrder == null) { // 订单是否为空
			return false;
		}
		// 抢单人id
		if (ToolUtil.isBlank(reqCompetitiveOrder.getGrabOrderUserId())) {
			return false;
		}
		// 订单id
		if (ToolUtil.isBlank(reqCompetitiveOrder.getOid())) {
			return false;
		}
		// 抢单人用户角色
		if (reqCompetitiveOrder.getUserType() == null) {
			return false;
		}

		return true;
	}

	/**
	 * @Title: sendMessage @Description: 用户抢单-给下单用户发送短信 @param
	 *         reqCompetitiveOrder 用户抢单客户端请求参数 @param placeOrderUserId
	 *         下单ID @return void 返回类型 @throws
	 */
	public void sendMessage(ReqCompetitiveOrder reqCompetitiveOrder, PushCompetitiveOrder pushCompetitiveOrder) {

		if (pushCompetitiveOrder == null || ToolUtil.isBlank(pushCompetitiveOrder.getAnotherPhoneNo())) {
			log.error("发送短信出现异常，获取到的手机号为空！类：" + this.getClass() + "方法：competitiveOrder()");
		}

		// 获取待发送的手机号
		String tellPhone = pushCompetitiveOrder.getAnotherPhoneNo();

		// 获取发送短信内容
		String sendMessageText = null;
		// 判断当前用户角色是什么类型
		if (reqCompetitiveOrder.getUserType() == 2) { // 乘客抢单，发送短信给司机
			sendMessageText = MessageModel.PASSENGER_GRAB_ORDER;
		} else if (reqCompetitiveOrder.getUserType() == 1) { // 司机抢单，发送短信给乘客
			sendMessageText = MessageModel.DRIVER_GRAB_ORDER;
		}

		// 发送短信
		MessageRequestsDTO messageRequestsDTO = new MessageRequestsDTO();
		messageRequestsDTO.setTelPhone(tellPhone);
		messageRequestsDTO.setMessageContent(sendMessageText);
		Boolean flag = queuefacade.addMessageToQueue(JSONUtil.toJSONString(messageRequestsDTO));

		if (!flag) {
			log.info("用户抢单时给下单用户发送短信失败   类：" + this.getClass() + " sendMessage()");
		}

	}

	/**
	 * @Title: sendPush @Description: 用户抢单，给下单用户发送短信 @param reqCompetitiveOrder
	 *         用户抢单，客户端请求参数 @param pushCompetitiveOrder 推送内容 @return void
	 *         返回类型 @throws
	 */
	public boolean sendPush(ReqCompetitiveOrder reqCompetitiveOrder, PushCompetitiveOrder pushCompetitiveOrder,
			String modular) {

		String registrationID = pushCompetitiveOrder.getPublishOrderUserId();

		String alert = null; // 通知标题
		String msgTitle = null; // 内容标题

		// 创建推送Bean
		PushData pushData = new PushData();

		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular(modular);
		// 推送内容
		pushData.setResponseBody(pushCompetitiveOrder);

		String msgContent = JSONUtil.toJSONString(pushData, "yyyy-MM-dd HH:mm:ss"); // 推送内容
		String sysType = pushCompetitiveOrder.getLoginEquipment(); // 设备类型

		// 当前用户类型
		Integer userType = reqCompetitiveOrder.getUserType();

		if (userType == 2) { // 当前用户类型为乘客
			alert = PushModel.ORDER_ALREADY_ROBBED_DRIVER;
			msgTitle = PushModel.ORDER_ALREADY_ROBBED_DRIVER;
		} else if (userType == 1) { // 当前用户类型为司机
			alert = PushModel.ORDER_ALREADY_ROBBED_PASSENGER;
			msgTitle = PushModel.ORDER_ALREADY_ROBBED_PASSENGER;
		}

		// 用户抢单，推送消息
		boolean flag = SendPushUtil.sendPush(registrationID, alert, msgTitle, msgContent, sysType);

		if (!flag) {
			log.info("用户抢单时，给下单用户推送消息失败   类：" + this.getClass() + " sendPush()");
		}

		return flag;
	}

	/**
	 * @Title: sendEmail
	 * @Description: 发送邮件
	 * @author yuHaiQing
	 * @return boolean    返回类型
	 * @throws
	 */
	public boolean sendEmail(Object object, Userordert userordert) {

		Map<String, Object> title = new HashMap<String, Object>();

		String orderStr = "";

		if (userordert.getIsLongDistance() == 1) {
			orderStr = "(同城)";
		} else if (userordert.getIsLongDistance() == 2) {
			orderStr = "(长途)";
		}

		title.put("orderType", orderStr);

		// 邮件内容
		Map<String, Object> root = new HashMap<String, Object>();

		root.put("oid", userordert.getOid());// 订单Id

		if (object instanceof PushCompetitiveOrder) {
			PushCompetitiveOrder pushCompetitiveOrder = (PushCompetitiveOrder) object;

			root.put("lisencePlate", pushCompetitiveOrder.getLicensePlate());// 车牌号
			root.put("driverName", pushCompetitiveOrder.getDriverName());// 司机姓名

			title.put("orderStatus", "(接单)");

		} else if (object instanceof PushAutomaticCancelOrder) {
			PushAutomaticCancelOrder pushAutomaticCancelOrder = (PushAutomaticCancelOrder) object;

			root.put("lisencePlate", pushAutomaticCancelOrder.getLisencePlate());// 车牌号
			root.put("driverName", pushAutomaticCancelOrder.getDriverName());// 司机姓名

			title.put("orderStatus", "(已取消)");

		}

		root.put("createTime", userordert.getCreateTime());// 下单时间
		root.put("setOutTime", userordert.getSetOutTime());// 出发时间
		root.put("startAddress", userordert.getStartAddress());// 起点
		root.put("endAddress", userordert.getEndAddress());// 终点

		try {
			super.emailSend.senMail(title, "emailTitle.ftl", root, "emailContext.ftl");
		} catch (Exception e) {
			log.error("发送邮件时出现异常  类：" + this.getClass() + " sendEmail()", e);
			return false;
		}

		return true;
	}

	/**
	 * 
	 * @Title: getOrderStatus @Description:获取订单状态，如果订单状态为待抢单（1）
	 *         将更改订单状态为已抢单 @author cheshaowei @throws
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	private Userordert getOrderStatus(ReqCompetitiveOrder reqCompetitiveOrder, DataResponse dataResponse) {

		// 查询到的订单信息
		Userordert userordert = null;

		try {
			// 防止事务提交不及时
			Thread.sleep(200);

			String orderId = reqCompetitiveOrder.getOid();
			// 查询要抢的订单
			userordert = super.userOrderTDao.getById(orderId, false);

			if (userordert == null) {
				// 当前订单不存在
				setStatus(dataResponse, SystemCode.ORDER_NOT_EXIST_ERROR);
				return null;
			}

			// 判断该用户是否存在未完成订单
			List<Userordert> userorderts = this.existNotCompleteOrder(reqCompetitiveOrder.getGrabOrderUserId());

			// 判断如果当前用户存在两个未完成订单，则驳回下单
			if (userorderts != null && userorderts.size() == 2) {
				setStatus(dataResponse, SystemCode.USER_ORDERT_TOO_MANY_ERROR);
				return null;
			}

			// 判断自身是否存在与目标订单类型相同的订单 false 不存在 true 存在
			boolean flag = false;

			if (userorderts != null) {

				for (Userordert uot : userorderts) {
					// 判断自身是否存在与目标订单类型相同的订单，存在则不能抢单
					if (userordert.getIsLongDistance() != null
							&& userordert.getIsLongDistance().equals(uot.getIsLongDistance())) {

						if (uot.getIsLongDistance() == 1) {
							// 您已有短途单，不能再抢短途单
							setStatus(dataResponse, SystemCode.USER_GRAB_ORDERT_NOT_SHORT_SAME_ERROR);
						} else {
							// 您已有长途单，不能再抢长途单
							setStatus(dataResponse, SystemCode.USER_GRAB_ORDERT_NOT_SAME_LONG_ERROR);
						}

						flag = true;
						break;
					}
				}

			}

			if (flag) {
				return null;
			}

			// 获取订单状态
			boolean isSuccess = getOrderCacheStatus(reqCompetitiveOrder, dataResponse);

			if (isSuccess == false) { // 订单已被抢
				setStatus(dataResponse, SystemCode.USER_GRAB_ORDER_ERROR);
				return null;
			}

			// 获取当前订单状态
			int orderStatus = userordert.getOrderStatus();

			if (orderStatus == ServiceCode.ORDER_STATUS_WAITING) { // 待抢单
				// 2:已被抢（待支付）
				userordert.setOrderStatus(ServiceCode.ORDER_STATUS_PAY);
				// 抢单用户
				userordert.setGrabOrderUserId(reqCompetitiveOrder.getGrabOrderUserId());
				// 抢单时间
				userordert.setGrabOrderTime(new Date());

				if (reqCompetitiveOrder.getUserType() == 2) {
					// 用户优惠券Id
					userordert.setUcId(reqCompetitiveOrder.getUcId());

					// 优惠金额
					userordert.setCouponMoney(reqCompetitiveOrder.getCouponMoney());
				}

				setStatus(dataResponse, SystemCode.SUCCESS);
			} else if (orderStatus == ServiceCode.ORDER_STATUS_PAY || orderStatus == ServiceCode.ORDER_STATUS_PAID) { // 订单已被抢
				setStatus(dataResponse, SystemCode.USER_GRAB_ORDER_ERROR);
				return null;
			}

		} catch (Exception e) {
			log.error("线程等待出现异常！类：" + this.getClass() + "方法：competitiveOrder()", e);
			return null;
		}

		return userordert;
	}

	@Override
	public void setStatus(DataResponse dataResponse, int status) {

		String message = null;
		switch (status) {
		case SystemCode.SUCCESS:
			message = SystemCode.SUCCESS_MESSAGE;
			break;
		case SystemCode.ERROR:
			message = SystemCode.ERROR_MESSAGE;
			break;
		case SystemCode.USER_INFO_NOT_EXIST_ERROR: // 用户信息不存在
			message = SystemCode.USER_INFO_NOT_EXIST_MESSAGE;
			break;
		case SystemCode.CANCEL_ORDER_TOO_MUCH: // 取消次数超过三次
			message = SystemCode.CANCEL_ORDER_MUCH_MESSAGE;
			break;
		case SystemCode.PUBLISH_ORDER_TOO_MUCH: // 接单次数超过三次
			message = SystemCode.PUBLISH_ORDER_TOO_MUCH_MESSAGE;
			break;
		case SystemCode.DATA_NULL_ERROR: // 请求数据为空
			message = SystemCode.DATA_NULL_MESSAGE;
			break;
		case SystemCode.ORDER_NOT_EXIST_ERROR: // 订单不存在
			message = SystemCode.ORDER_NOT_EXIST_MESSAGE;
			break;
		case SystemCode.USER_GRAB_ORDER_ERROR: // 订单已被抢
			message = SystemCode.USER_GRAB_ORDER_MESSAGE;
			break;
		case SystemCode.SET_OUT_TIME_ERROR: // 发单时间有误
			message = SystemCode.SET_OUT_TIME_MESSAGE;
			break;
		case SystemCode.USER_PLACE_ORDER_ERROR: // 您尚有未完成订单
			message = SystemCode.USER_PLACE_ORDER_MESSAGE;
			break;
		case SystemCode.USER_ORDERT_TOO_MANY_ERROR:// 您的未完成订单次数过多
			message = SystemCode.USER_ORDERT_TOO_MANY_MESSAGE;
			break;
		case SystemCode.USER_GRAB_ORDERT_NOT_SHORT_SAME_ERROR:
			message = SystemCode.USER_GRAB_ORDERT_NOT_SHORT_SAME_MESSAGE;// 已存在同类型的订单，不能再下相同类型的单
			break;
		case SystemCode.USER_GRAB_ORDERT_NOT_SAME_LONG_ERROR:
			message = SystemCode.USER_GRAB_ORDERT_NOT_LONG_SAME_MESSAGE;// 已存在同类型的订单，不能再下相同类型的单
			break;
		case SystemCode.USER_ORDERT_NOT_SAME_SHORT_ERROR:
			message = SystemCode.USER_ORDERT_NOT_SAME_SHORT_MESSAGE;// 您已存在短途单，不能再发短途订单！
			break;
		case SystemCode.USER_ORDERT_NOT_SAME_LONG_ERROR:
			message = SystemCode.USER_ORDERT_NOT_SAME_LONG_MESSAGE;// 您已存在长途单，不能再发长途订单！
			break;
		default:
			break;
		}
		dataResponse.setResponseCode(status);
		dataResponse.setResponseMessage(message);
	}

	/**
	 * @Title: userNewestAddress @Description: 用户最新地址 @param userLocation
	 *         用户的最新地址信息 @return void 返回类型 @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void userNewestAddress(UserLocation userLocation, DataResponse dataResponse) {

		// 验证客户端传入参数是否为空
		boolean flag = validateUserNewestAddressParam(userLocation);

		if (!flag) {

			log.info("更新用户最新地址时客户端传入的参数为空  类：" + this.getClass() + " userNewestAddress()");
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
		}

		// 产生一个更新用户最新地址的主键
		userLocation.setUlId(ToolUtil.getUid());
		// 更新时间
		userLocation.setCreateTime(new Date());

		try {
			super.userLocationDao.save(userLocation);
		} catch (Exception e) {
			log.info("更新用最新地址时出现异常 类：" + this.getClass() + " userNewestAddress()", e);
			setStatus(dataResponse, SystemCode.ERROR);
		}

		setStatus(dataResponse, SystemCode.SUCCESS);
	}

	/**
	 * @Title: validateUserNewestAddressParam @Description:
	 *         判断最新用户地址传入的参数是否为空 @param userLocation 客户端传入参数 @return boolean
	 *         返回类型 @throws
	 */
	public boolean validateUserNewestAddressParam(UserLocation userLocation) {

		// 判断客户端传入参数是否为空，如果为空返回false, 否则返回true
		if (userLocation == null || ToolUtil.isBlank(userLocation.getLoginId())
				|| ToolUtil.isBlank(userLocation.getOrderId())) {

			return false;

		}

		return true;
	}

	/**
	 * @Title: getNearbyUserList
	 * @Description: 获取附近列表(乘客列表/车主列表)
	 * @param dataResponse
	 * @param reqGetNearbyUserList
	 * @return void 返回类型
	 */
	@Override
	@Transactional(readOnly = true)
	public void getNearbyUserList(ReqGetNearbyUserList reqGetNearbyUserList, DataResponse dataResponse) {

		// 判断获取附近列表传入参数是否为空
		boolean isTrue = this.isValidateGetNearbyUserListParamTrue(reqGetNearbyUserList);

		// 如果存在空数据
		if (!isTrue) {
			log.error("获取附近乘客列表请求参数为空:" + reqGetNearbyUserList.toString());
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return;
		}

		ResNearbyUserInfo resNearbyUserInfo = new ResNearbyUserInfo();

		// 获取附近用户列表
		List<NearbyOrderList> getNearbyUserList = super.userOrderTDao.getNearbyUserLists(reqGetNearbyUserList);

		if (reqGetNearbyUserList.getUserType() == 2) {
			// 如果用户为乘客，则返回优惠券信息
			boolean flag = this.getCoupon(resNearbyUserInfo, reqGetNearbyUserList.getUserId());

			// 如果查询失败，则终止操作
			if (!flag) {
				setStatus(dataResponse, SystemCode.ERROR);
				return;
			}
		} else {
			resNearbyUserInfo.setCoupon(new Coupon("", 0));
		}

		// 判断获取附件用户列表是否为空
		if (getNearbyUserList != null && getNearbyUserList.size() > 0) {
			resNearbyUserInfo.setNearbyOrderList(getNearbyUserList);
		}

		// 响应数据
		dataResponse.setResponseBody(resNearbyUserInfo);

		setStatus(dataResponse, SystemCode.SUCCESS);
	}

	/**
	 * @Title: getNearbyOrderList 
	 * @Description: 获取附近列表(乘客列表/车主列表)(V1.9.0新接口)
	 * @param dataResponse
	 * @param reqGetNearbyOrderList
	 * @return void    返回类型 
	 * @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public void getNearbyOrderList(ReqGetNearbyOrderList reqGetNearbyOrderList, DataResponse dataResponse) {

		// 判断获取附近列表传入参数是否为空
		boolean isTrue = this.isValidateGetNearbyOrderListParamTrue(reqGetNearbyOrderList);

		// 如果存在空数据
		if (!isTrue) {
			log.error("获取附近乘客列表请求参数为空:" + reqGetNearbyOrderList.toString());
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return;
		}

		ResNearbyUserInfo resNearbyUserInfo = new ResNearbyUserInfo();

		// 获取附近用户列表
		List<NearbyOrderList> getNearbyUserList = super.userOrderTDao.getNearbyOrderLists(reqGetNearbyOrderList);

		if (reqGetNearbyOrderList.getUserType() == 2) {
			// 如果用户为乘客，则返回优惠券信息
			boolean flag = this.getCoupon(resNearbyUserInfo, reqGetNearbyOrderList.getUserId());

			// 如果查询失败，则终止操作
			if (!flag) {
				setStatus(dataResponse, SystemCode.ERROR);
				return;
			}
		} else {
			resNearbyUserInfo.setCoupon(new Coupon("", 0));
		}

		// 判断获取附件用户列表是否为空
		if (getNearbyUserList != null && getNearbyUserList.size() > 0) {
			resNearbyUserInfo.setNearbyOrderList(getNearbyUserList);
		}

		// 响应数据
		dataResponse.setResponseBody(resNearbyUserInfo);

		setStatus(dataResponse, SystemCode.SUCCESS);
	}

	/**
	 * @Title: getCoupon 
	 * @Description: 获取优惠券 
	 * @author YHQ
	 * @return Coupon    返回类型 
	 * @throws
	 */
	public boolean getCoupon(ResNearbyUserInfo resNearbyUserInfo, String userId) {

		// 添加获取优惠券信息条件
		Criterion criterion = Restrictions.and(Restrictions.eq("loginId", userId), Restrictions.eq("couponStatus", 2));

		List<UserCoupon> userCoupons = null;

		try {
			userCoupons = super.userCouponDao.queryCriteriaListByOrderDesc(criterion, "couponMoney", false);
		} catch (Exception e) {
			log.error("根据用户获取优惠券信息时出现异常  类：" + this.getClass() + " getNearbyUserList()", e);
			return false;
		}

		if (userCoupons != null && userCoupons.size() > 0) {

			// 获取优惠金额最小的优惠券信息
			UserCoupon userCoupon = userCoupons.get(userCoupons.size() - 1);

			// 判断优惠券信息是否为空
			if (userCoupon != null && ToolUtil.isNotBlank(userCoupon.getUcId())
					&& userCoupon.getCouponMoney() != null) {

				// 创建优惠券信息对象
				Coupon coupon = new Coupon();

				// 用户优惠券ID
				coupon.setUcId(userCoupon.getUcId());
				// 优惠券金额
				coupon.setCouponMoney(userCoupon.getCouponMoney());

				resNearbyUserInfo.setCoupon(coupon);
			}

		} else {
			resNearbyUserInfo.setCoupon(new Coupon("", 0));
		}

		return true;
	}

	/**
	 * @Title: validateGetNearbyUserListParam @Description:
	 *         验证获取附近列表(乘客列表/车主列表)的参数是否为空 @param reqGetNearbyUserList
	 *         客户端传入参数 @return true 参数正确 false 参数错误 @throws
	 */
	private boolean isValidateGetNearbyUserListParamTrue(ReqGetNearbyUserList reqGetNearbyUserList) {

		// 判断传入对象是否为空
		if (reqGetNearbyUserList == null) {
			return false;
		}

		// 用户角色 1：车主 2：乘客
		if (reqGetNearbyUserList.getUserType() == null) {
			return false;
		}
		// 当前用户Id
		if (reqGetNearbyUserList.getUserId() == null) {
			return false;
		}
		// 筛选条件（1：附近 2：顺路 3：长途）
		if (reqGetNearbyUserList.getScreenCondition() == null) {
			return false;
		}
		// 排序条件（1:最早出发 2：离我最近 3：女士优先 4：男士优先）
		if (reqGetNearbyUserList.getSortCondition() == null) {
			return false;
		}
		// 用户当前位置经度
		if (reqGetNearbyUserList.getCurrentLongitude() == null) {
			return false;
		}
		// 用户当前位置纬度
		if (reqGetNearbyUserList.getCurrentLatitude() == null) {
			return false;
		}

		// 判断如果筛选条件为长途，则要判断用户所在城市是否为空
		if (reqGetNearbyUserList.getScreenCondition().equals(3)) {
			// 所在城市
			if (reqGetNearbyUserList.getPayCity() == null) {
				return false;
			}
		}

		// 每页显示记录数
		if (reqGetNearbyUserList.getPageSize() == null) {
			return false;
		}
		// 当前页
		if (reqGetNearbyUserList.getPageIndex() == null) {
			return false;
		}

		return true;
	}

	/**
	 * @Title: isValidateGetNearbyOrderListParamTrue 
	 * @Description: 验证获取附近列表(乘客列表/车主列表)的参数是否为空
	 * @param reqGetNearbyUserList 客户端传入参数 
	 * @return true 参数正确 false 参数错误 
	 * @throws
	 */
	private boolean isValidateGetNearbyOrderListParamTrue(ReqGetNearbyOrderList reqGetNearbyOrderList) {

		// 判断传入对象是否为空
		if (reqGetNearbyOrderList == null) {
			return false;
		}

		// 用户角色 1：车主 2：乘客
		if (reqGetNearbyOrderList.getUserType() == null) {
			return false;
		}
		// 当前用户Id
		if (reqGetNearbyOrderList.getUserId() == null) {
			return false;
		}
		// 筛选条件（1：上班 2：下班 3：附近 4：顺路）
		if (reqGetNearbyOrderList.getScreenCondition() == null) {
			return false;
		}
		// 排序条件（1:最早出发 2：离我最近 3：女士优先 4：男士优先）
		if (reqGetNearbyOrderList.getSortCondition() == null) {
			return false;
		}
		// 用户当前位置经度
		if (reqGetNearbyOrderList.getCurrentLongitude() == null) {
			return false;
		}
		// 用户当前位置纬度
		if (reqGetNearbyOrderList.getCurrentLatitude() == null) {
			return false;
		}

		// 判断如果筛选条件为长途，则要判断用户所在城市是否为空
		if (reqGetNearbyOrderList.getScreenCondition().equals(3)) {
			// 所在城市
			if (reqGetNearbyOrderList.getPayCity() == null) {
				return false;
			}
		}

		// 每页显示记录数
		if (reqGetNearbyOrderList.getPageSize() == null) {
			return false;
		}
		// 当前页
		if (reqGetNearbyOrderList.getPageIndex() == null) {
			return false;
		}

		return true;
	}

	/**
	 * 计算距离价格
	 */
	@Override
	public void calculateDistance(ReqCalculateDistance reqCalculateDistance, DataResponse dataResponse) {

		// 验证请求数据
		boolean flag = this.validateCalculateDistance(reqCalculateDistance);

		if (!flag) {
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return;
		}

		// 获取判断长途是否为条件
		LongDistanceConfig longDistanceConfig = OrderCache.longDistanceConfig();

		// 两点之间的距离
		CalculatDistanceDTO calculatDistanceDTO = GetDistanceUtil.getSingleDistance(
				reqCalculateDistance.getStartLongitude(), reqCalculateDistance.getStartLatitude(),
				reqCalculateDistance.getEndLongitude(), reqCalculateDistance.getEndLatitude());

		BigDecimal distance = calculatDistanceDTO.getDistance();

		Integer isLongDistance = null;

		// 判断该订单是普通还是长途订单
		if (distance.compareTo(longDistanceConfig.getLongDistance()) > 0) {
			isLongDistance = 2;// 长途
		} else {
			isLongDistance = 1;// 普通
		}

		// 获取两点之间的距离
		String disString = String.valueOf(distance);

		// 读取全部计费规则数据
		List<Stageprice> stageprices = super.stagePriceService.getOrderPriceRule();

		double price = 0;

		// 存在计费规则
		if (stageprices != null && distance.compareTo(new BigDecimal(0)) > 0) {
			price = OrderPriceUtil.getOrderPriceByDistance(distance.doubleValue(), stageprices);
		}

		// 四舍五入
		price = Double.valueOf(new BigDecimal(price).setScale(0, BigDecimal.ROUND_HALF_UP).toString());

		// 获取优惠券信息
		ResCoupon resCoupon = super.userAccountService.getResCoupon(reqCalculateDistance.getUserID());

		// 创建计算距离价格的对象，并为其赋值
		ResCalculateDistance resCalculateDistance = new ResCalculateDistance();

		resCalculateDistance.setDistance(String.valueOf(distance));// 距离
		resCalculateDistance.setTotalMoney(price);// 总价格
		resCalculateDistance.setIsLongDistance(isLongDistance);// 长短途 1:普通 2:长途
		resCalculateDistance.setOrderCost(price - 2);// 订单费用
		resCalculateDistance.setPlatformCost(ToolUtil.castDouble(2));// 平台费用

		// 判断优惠券信息是否为空
		if (resCoupon != null && ToolUtil.isNotBlank(resCoupon.getUcId()) && resCoupon.getCouponMoney() != null) {
			resCalculateDistance.setUcId(resCoupon.getUcId());// 用户优惠券Id
			resCalculateDistance.setCouponMoney(resCoupon.getCouponMoney());// 优惠金额
		}

		setStatus(dataResponse, SystemCode.SUCCESS);
		dataResponse.setResponseBody(resCalculateDistance);
		return;
	}

	/**
	 * @Title: validateCalculateDistance @Description:验证计算距离接口的请求数据 @param
	 *         reqCalculateDistance @author lijinchao @return true 参数正确 false
	 *         参数有误 @throws
	 */
	private boolean validateCalculateDistance(ReqCalculateDistance reqCalculateDistance) {

		if (reqCalculateDistance == null || ToolUtil.isBlank(reqCalculateDistance.getUserID())// 用户Id
				|| reqCalculateDistance.getStartLongitude() == null // 起点经度
				|| reqCalculateDistance.getStartLatitude() == null // 起点纬度
				|| reqCalculateDistance.getEndLongitude() == null // 终点经度
				|| reqCalculateDistance.getEndLatitude() == null) { // 终点纬度

			return false;
		}

		return true;
	}

	/**
	 * @Title: getPushData @Description: 向同城用户推送的数据 @param userdetail
	 *         用户详情 @param userordert 订单 @param modular 模块名称 @author
	 *         lijinchao @return PushData @throws
	 */
	private String getPushData(Userdetail userdetail, Userordert userordert, String modular) {
		// 创建推送数据
		PushData pushData = new PushData();
		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular(modular);

		ResGetNearbyUserList resGetNearbyUserList = new ResGetNearbyUserList();
		/*
		 * // 发单人id
		 * resGetNearbyUserList.setPassengerId(userordert.getPlaceOrderUserId())
		 * ; // 订单id resGetNearbyUserList.setOid(userordert.getOid()); // 用户名称
		 * resGetNearbyUserList.setNickName(userdetail.getNickName()); // 用户头像地址
		 * if (userdetail.getUserAvatar() != null) {
		 * resGetNearbyUserList.setUserAvatar(ToolUtil.imageAddress(userdetail.
		 * getUserAvatar())); } // 头像缩略图地址 if (userdetail.getUserTabloidAvatar()
		 * != null) {
		 * resGetNearbyUserList.setUserTabloidAvatar(ToolUtil.imageAddress(
		 * userdetail.getUserTabloidAvatar())); } // 手机号
		 * resGetNearbyUserList.setTellPhone(userdetail.getTellphone()); // 出发时间
		 * resGetNearbyUserList.setSetOutTime(DateFormatUtil.getMMddEHHss(
		 * userordert.getSetOutTime())); // 起点
		 * resGetNearbyUserList.setStartAddress(userordert.getStartAddress());
		 * // 起点经度
		 * resGetNearbyUserList.setStartLongitude(userordert.getStartLongitude()
		 * ); // 起点纬度
		 * resGetNearbyUserList.setStartLatitude(userordert.getStartLatitude());
		 * // 终点 resGetNearbyUserList.setEndAddress(userordert.getEndAddress());
		 * // 终点经度
		 * resGetNearbyUserList.setEndLongitude(userordert.getEndLongitude());
		 * // 终点纬度
		 * resGetNearbyUserList.setEndLatitude(userordert.getEndLatitude()); //
		 * 价格 resGetNearbyUserList.setTotalMoney(userordert.getTotalMoney()); //
		 * 订单状态
		 * resGetNearbyUserList.setOrderStatus(userordert.getOrderStatus()); //
		 * 红包 resGetNearbyUserList.setRedBag(userordert.getRedBag()); // 留言 if
		 * (userordert.getMessage() != null) {
		 * resGetNearbyUserList.setMessage(userordert.getMessage()); } // 人数
		 * resGetNearbyUserList.setNumber(userordert.getNumber());
		 */

		// 同城推送暂不添加内容
		pushData.setResponseBody(resGetNearbyUserList);

		String msgContent = JSONUtil.toJSONString(pushData, "yyyy-MM-dd HH:mm:ss"); // 推送内容

		return msgContent;
	}

	/**
	 * @Title: automaticCancel @Description: 自动取消订单 @author yhq @return
	 *         void @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void automaticCancel() {

		// 将List<Object[]>转为List<Userordert>类型
		List<PushAutomaticCancelOrder> list = super.userOrderTDao.getCancelOrders();

		// 判断待取消订单列表是否为空
		if (list != null && list.size() > 0) {
			log.info("存在符合自动取消条件的订单");
			// 遍历过期订单，并执行关闭操作
			for (PushAutomaticCancelOrder pushAutomaticCancelOrder : list) {
				// 取消订单操作
				this.cancelOperation(pushAutomaticCancelOrder);
			}
		}
	}

	/**
	 * @Title: batchHandle 
	 * @Description: 批量处理待取消订单 
	 * @return boolean 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean batchHandle() {

		try {
			// 批量处理待取消订单
			super.userOrderTDao.addNativeSQLRow(UserOrderDaoSql.BATCH_HANDLE);
		} catch (Exception e) {
			log.error("批量处理可自动取消订单时出现异常  类：" + this.getClass() + " batchHandle()", e);
			return false;
		}

		return true;
	}

	/**
	 * @Title: batchDelete @Description: 批量删除待取消订单 @return boolean 返回类型 @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean batchDelete() {
		try {
			// 删除之前的待取消订单
			super.userOrderTDao.updateSqlRow(UserOrderDaoSql.BATCH_DELETE);
		} catch (Exception e) {
			log.error("批量删除自动取消订单时出现异常  类：" + this.getClass() + " batchHandle()", e);
			return false;
		}

		return true;
	}

	/**
	 * @Title: cancelOperation 
	 * @Description: 自动取消操作 
	 * @param userordert 
	 * @author yhq 
	 * @return void 
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean cancelOperation(PushAutomaticCancelOrder pushAutomaticCancelOrder) {

		if (ToolUtil.isNotBlank(pushAutomaticCancelOrder.getUcId())) {
			// 添加查询条件
			Criterion criter = Restrictions.eq("ucId", pushAutomaticCancelOrder.getUcId());

			UserCoupon userCoupon = super.userCouponDao.queryCriteriaUnResult(criter, false);

			if (userCoupon != null && userCoupon.getCouponStatus() != null && userCoupon.getCouponStatus() == 3) {
				userCoupon.setCouponStatus(2);
			}
		}

		// 参加活动,类型为自动完成订单
		BigDecimal integral = activityService.attendActivity(pushAutomaticCancelOrder.getDriverId(),
				AttendActivityEnum.CANCEL_ORDER);
		if (integral.compareTo(new BigDecimal(0)) != 0) {
			// 将参加活动所赠积分添加到订单表中
			boolean status = userOrderTDao.updateCurrentOrderReceiveIntegral(integral,
					pushAutomaticCancelOrder.getOid());
		}
		log.info("自动取消返回的积分是：" + integral);
		pushAutomaticCancelOrder.setIntegral(integral);

		// 给乘客发送短信，推送消息
		if (ToolUtil.isNotBlank(pushAutomaticCancelOrder.getPassengerId())) {
			// 给乘客发送短信
			MessageRequestsDTO messageRequestsDTO = new MessageRequestsDTO();
			messageRequestsDTO.setTelPhone(pushAutomaticCancelOrder.getPassengerPhone());
			messageRequestsDTO.setMessageContent(
					MessageModel.autoCancelOrder(pushAutomaticCancelOrder.getPassengerName(), 0));
			queuefacade.addMessageToQueue(JSONUtil.toJSONString(messageRequestsDTO));
			// 推送Bean
			PushData pushData = new PushData();

			// 推送序号(时间戳)
			pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
			// 推送时间
			pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
			// 模块
			pushData.setModular(ServiceCode.CANEL_ORDER);
			// 推送内容
			pushData.setResponseBody(pushAutomaticCancelOrder);

			// 给乘客推送消息
			SendPushUtil.sendPush(pushAutomaticCancelOrder.getPassengerAliasId(), PushModel.AUTO_CANCEL_ORDER,
					PushModel.AUTO_CANCEL_ORDER, JSONUtil.toJSONString(pushData),
					pushAutomaticCancelOrder.getPassengerEquipment());

		}

		// 给司机发送短信，推送消息
		if (ToolUtil.isNotBlank(pushAutomaticCancelOrder.getDriverId())) {
			// 给司机发送短信
			MessageRequestsDTO messageRequestsDTO = new MessageRequestsDTO();
			messageRequestsDTO.setTelPhone(pushAutomaticCancelOrder.getDriverPhone());
			messageRequestsDTO.setMessageContent(
					 MessageModel.autoCancelOrder(pushAutomaticCancelOrder.getDriverName(), pushAutomaticCancelOrder.getIntegral().intValue()));
			queuefacade.addMessageToQueue(JSONUtil.toJSONString(messageRequestsDTO));
			// 推送Bean
			PushData pushData = new PushData();

			// 推送序号(时间戳)
			pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
			// 推送时间
			pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
			// 模块
			pushData.setModular(ServiceCode.CANEL_ORDER);
			// 推送内容
			pushData.setResponseBody(pushAutomaticCancelOrder);

			// 给司机推送消息
			SendPushUtil.sendPush(pushAutomaticCancelOrder.getDriverAliasId(), PushModel.AUTO_CANCEL_ORDER,
					PushModel.AUTO_CANCEL_ORDER, JSONUtil.toJSONString(pushData),
					pushAutomaticCancelOrder.getDriverEquipment());

		}

		if (pushAutomaticCancelOrder.getOrderStatus() != 1) {
			Userordert userordert = new Userordert();

			userordert.setOid(pushAutomaticCancelOrder.getOid());// 订单Id
			userordert.setCreateTime(pushAutomaticCancelOrder.getCreateTime());// 下单时间
			userordert.setSetOutTime(pushAutomaticCancelOrder.getSetOutTime());// 出发时间
			userordert.setStartAddress(pushAutomaticCancelOrder.getStartAddress());// 起点
			userordert.setEndAddress(pushAutomaticCancelOrder.getEndAddress());// 终点
			userordert.setIsLongDistance(pushAutomaticCancelOrder.getIsLongDistance());// 1:普通
																						// 2:长途

			// 发送邮件(未签订保险合同)
			this.sendEmail(pushAutomaticCancelOrder, userordert);
		}

		return true;

	}

	/**
	 * @Title: getUserorder @Description: 将UserOrdert中的数据赋值给UserOrder @param
	 *         userOrdert 订单临时表对象中的数据 @author yhq @return UserOrder
	 *         订单正式表对象 @throws
	 */
	public Userorder getUserorder(Userordert userordert) {

		// 创建userOrder对象
		Userorder userOrder = new Userorder();
		// 主键Id
		userOrder.setOid(userordert.getOid());
		// 下单用户Id
		userOrder.setPlaceOrderUserId(userordert.getPlaceOrderUserId());
		// 下单城市
		userOrder.setPayCity(userordert.getPayCity());
		// 出发时间
		userOrder.setSetOutTime(userordert.getSetOutTime());
		// 出发地址
		userOrder.setStartAddress(userordert.getStartAddress());
		// 起点经度
		userOrder.setStartLongitude(userordert.getStartLongitude());
		// 起点纬度
		userOrder.setStartLatitude(userordert.getStartLatitude());
		// 目的地
		userOrder.setEndAddress(userordert.getEndAddress());
		// 目的地经度
		userOrder.setEndLongitude(userordert.getEndLongitude());
		// 目的地纬度
		userOrder.setEndLatitude(userordert.getEndLatitude());
		// 距离
		userOrder.setDistance(userordert.getDistance());
		// 叮币支付金额
		userOrder.setPayMoney(userordert.getPayMoney());
		// 支付宝支付金额
		userOrder.setAlipayMoney(userordert.getAlipayMoney());
		// 总金额
		userOrder.setTotalMoney(userordert.getTotalMoney());
		// 人数
		userOrder.setNumber(userordert.getNumber());
		// 红包
		userOrder.setRedBag(userordert.getRedBag());
		// 留言
		userOrder.setMessage(userordert.getMessage());
		// 距对方距离
		userOrder.setPayDistance(userordert.getPayDistance());
		// 标志建筑物
		userOrder.setMarker(userordert.getMarker());
		// 抢单用户Id
		userOrder.setGrabOrderUserId(userordert.getGrabOrderUserId());
		// 抢单时间
		userOrder.setGrabOrderTime(userordert.getGrabOrderTime());
		// 订单状态
		userOrder.setOrderStatus(userordert.getOrderStatus());
		// 下单时间
		userOrder.setCreateTime(userordert.getCreateTime());
		// 订单支付时间
		userOrder.setPayTime(userordert.getPayTime());
		// 乘客确认到达时间
		userOrder.setEndTime(userordert.getEndTime());
		// 取消订单时间
		userOrder.setCancelTime(new Date());
		// 下单用户类型
		userOrder.setOrderType(userordert.getOrderType());
		// 取消类型
		userOrder.setCancelType(userordert.getCancelType());
		// 订单取消原因
		userOrder.setCancelDesc(userordert.getCancelDesc());

		return userOrder;
	}

	/**
	 * @Title: addCancelNumber @Description: 给主动取消的用户添加一个 @param @return void
	 *         返回类型 @throws
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void addCancelNumber(String userId) {
		// 添加一个用户Id作为查询条件
		Criterion criterion = Restrictions.eq("uid", userId);

		// 根据用户Id获取登录信息
		UserLogin userLogin = super.userLoginDao.queryCriteriaUnResult(criterion, false);

		// 判断如果登录信息不为空，则给该用户增加一次取消
		if (userLogin != null) {
			userLogin.setCancelNumber(userLogin.getCancelNumber() + 1);
		}

	}

	/**
	 * @Title: existNotCompleteOrder @Description: 根据用户Id判断该用户是否存在未完成订单 @param
	 *         userId 用户Id @author yhq @return boolean 返回类型 (true:存在
	 *         false:不存在) @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public List<Userordert> existNotCompleteOrder(String userId) {

		// 创建存储用户未完成订单对象
		List<Object[]> objects = null;

		try {
			objects = super.userOrderTDao.sqlQueryListObj(UserOrderDaoSql.EXIST_NOT_COMPLETE_ORDER, false, userId,
					userId);
		} catch (Exception e) {
			log.info("根据用户Id获取该用户未完成订单时出现异常   类：" + this.getClass() + " existNotCompleteOrder()", e);
			return null;
		}

		// 判断是否存在未完成订单
		if (objects.size() > 0) {

			// 数据转换
			return this.getUserOrdertList(objects);
		}

		return null;
	}

	/**
	 * @Title: getUserOrdertList @Description:
	 * 数据转换(将List<Object[]>转为List<Userordert>) @param objects 该用户未完成订单列表 @author
	 * yuHaiQing @return List<Userordert> 返回类型 @throws
	 */
	public List<Userordert> getUserOrdertList(List<Object[]> objects) {

		List<Userordert> userOrderts = new ArrayList<Userordert>();

		for (Object[] obj : objects) {

			Userordert userordert = new Userordert();

			// 订单Id
			if (obj[0] != null) {
				userordert.setOid(obj[0].toString());
			}
			// 下单用户Id
			if (obj[1] != null) {
				userordert.setPlaceOrderUserId(obj[1].toString());
			}
			// 出发时间
			if (obj[2] != null) {
				userordert.setSetOutTime((Date) obj[2]);
			}
			// 订单里程
			if (obj[3] != null) {
				userordert.setDistance(new BigDecimal(obj[3].toString()));
			}
			// 1: 普通 2: 长途
			if (obj[4] != null) {
				userordert.setIsLongDistance(ToolUtil.castInteger(obj[4]));
			}

			userOrderts.add(userordert);
		}

		return userOrderts;
	}

	/**
	 * @Title: userCurrentLocation
	 * @Description: 实时定位用户当前位置
	 * @param userLocation
	 *            用户的当前位置信息
	 * @param dataResponse
	 *            响应Bean
	 * @author yuHaiQing
	 * @return boolean 返回类型 @throws
	 * @Title: userCurrentLocation
	 * @Description: 实时定位用户当前位置
	 * @param reqUserLocation
	 *            用户的当前位置信息
	 * @param dataResponse
	 *            响应Bean
	 * @author yuHaiQing
	 * @return boolean
	 */

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public boolean userCurrentLocation(ReqUserLocation reqUserLocation, DataResponse dataResponse) {

		// 判断传入参数的经纬度
		if (reqUserLocation == null || ToolUtil.isBlank(reqUserLocation.getLoginId())
				|| ToolUtil.isBlank(reqUserLocation.getOrderId()) || reqUserLocation.getLongitude() == 0
				|| reqUserLocation.getLatitude() == 0 || ToolUtil.isBlank(reqUserLocation.getSetOutTime())) {

			// 客户端请求数据体为空22
			log.error("实时定位用户当前位置时请求参数为空    类：" + this.getClass() + " userCurrentLocation()");
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return false;

		}

		// 创建存储用户实时定位集合
		List<UserLocation> userLocations = new ArrayList<UserLocation>();

		// 获取订单Id集合
		String[] orderList = reqUserLocation.getOrderId().split(",");
		// 获取订单出发时间集合
		String[] setOutTime = reqUserLocation.getSetOutTime().split(",");

		try {
			for (int i = 0; i < orderList.length; i++) {

				// 订单出发时间
				Calendar oneTime = Calendar.getInstance();
				// 服务器当前时间
				Calendar twoTime = Calendar.getInstance();

				oneTime.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(setOutTime[i]));

				if (oneTime.getTimeInMillis() - twoTime.getTimeInMillis() >= 0) {

					// 创建更新用户最新地址Bean
					UserLocation userLocation = new UserLocation();
					// 创建用户当前位置的Id
					String ulId = ToolUtil.getUid();
					// 创建当前位置的时间
					Date date = new Date();
					// 添加用户当前位置Id
					reqUserLocation.setUlId(ulId);
					// 添加时间
					reqUserLocation.setCreateTime(date);

					// 数据转换
					this.getUserLocation(reqUserLocation, userLocation);

					// 订单Id
					userLocation.setOrderId(orderList[i]);

					userLocations.add(userLocation);
					Thread.sleep(10);
				}
			}
		} catch (ParseException e1) {
			log.error("时间格式转换异常  类：" + this.getClass() + " userCurrentLocation()", e1);
			setStatus(dataResponse, SystemCode.ERROR);
			return false;
		} catch (InterruptedException e1) {
			log.error("线程等待出现异常  类：" + this.getClass() + " userCurrentLocation()", e1);
			setStatus(dataResponse, SystemCode.ERROR);
			return false;
		}

		try {

			for (UserLocation userLocation : userLocations) {
				super.userLocationDao.save(userLocation);
			}
		} catch (Exception e) {
			log.info("实时定位用户当前位置时出现异常   类：" + this.getClass() + " userCurrentLocation()", e);
			setStatus(dataResponse, SystemCode.ERROR);
			return false;
		}
		setStatus(dataResponse, SystemCode.SUCCESS);
		return true;
	}

	/**
	 * 
	 * @Title: getMapShowRoute
	 * @Description:根据起、终点经纬度获取地图显示路线
	 * @param origin
	 *            出发点
	 * @param destination
	 *            目的地
	 * @author CHEHAUNBO
	 * @since v1.8
	 * @Override
	 * 
	 */
	public void getMapShowRoute(ReqGetMapShowRoute reqGetMapShowRoute, DataResponse dataResponse) {

		// 获取起始点经纬度
		if (reqGetMapShowRoute != null && ToolUtil.isBlank(reqGetMapShowRoute.getOrigin())
				&& ToolUtil.isBlank(reqGetMapShowRoute.getDestination())) {
			// 客户端请求数据体为空22
			log.error("获取地图显示路线客户端请求参数为空    类：" + this.getClass() + " userCurrentLocation()");
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
		}

		// 获取起点经纬度
		String origin = reqGetMapShowRoute.getOrigin();
		// 获取终点经纬度
		String destination = reqGetMapShowRoute.getDestination();

		// 获取地图显示路线
		List<ResGetMapShowRoute> mapRouteList = super.amapService.getMapShowRoute(origin, destination);

		if (mapRouteList != null) {
			dataResponse.setResponseBody(mapRouteList);
			setStatus(dataResponse, SystemCode.SUCCESS);
		} else {
			setStatus(dataResponse, SystemCode.ERROR);
		}

	}

	// 数据转换
	public UserLocation getUserLocation(ReqUserLocation reqUserLocation, UserLocation userLocation) {

		// 当前位置Id
		userLocation.setUlId(reqUserLocation.getUlId());
		// 经度
		userLocation.setLongitude(reqUserLocation.getLongitude());
		// 纬度
		userLocation.setLatitude(reqUserLocation.getLatitude());
		// 创建时间
		userLocation.setCreateTime(reqUserLocation.getCreateTime());
		// 用户Id
		userLocation.setLoginId(reqUserLocation.getLoginId());

		return userLocation;
	}

	/**
	 * @Title: getOrderInfoById
	 * @Description: 根据订单Id获取订单信息
	 * @param reqGetOrderInfo
	 *            客户端请求参数
	 * @param dataResponse
	 *            响应Bean
	 * @author yuHaiQing
	 * @return void 返回类型
	 */
	@Override
	@Transactional(readOnly = true)
	public void getOrderInfoById(ReqGetOrderInfo reqGetOrderInfo, DataResponse dataResponse) {

		if (reqGetOrderInfo == null || ToolUtil.isBlank(reqGetOrderInfo.getOid())) {
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			log.info("根据订单Id获取订单信息时，客户端传入参数为空");
			return;
		}

		// 根据订单Id获取订单信息
		ResGetOrderInfo resGetOrderInfo = super.userOrderTDao.getOrderInfo(reqGetOrderInfo.getOid());

		if (resGetOrderInfo == null) {
			setStatus(dataResponse, SystemCode.ERROR);
		} else {
			setStatus(dataResponse, SystemCode.SUCCESS);
		}

		// 设置数据响应体
		dataResponse.setResponseBody(resGetOrderInfo);

	}

	/**
	 * @Title: goToPay
	 * @Description:获取订单状态与用户钱包（点击去支付按钮时）
	 *  *****  2016年3月15日19:25:20 
	 * @param goToPay 客户端请求参数
	 * @param dataResponse 响应bean
	 * @author fengshuonan
	 * @Override
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void goToPay(ReqGoToPay goToPay, DataResponse dataResponse) {

		if (goToPay == null || ToolUtil.isBlank(goToPay.getOrderId()) || ToolUtil.isBlank(goToPay.getUserId())) {
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			log.error("获取订单状态与用户钱包（点击去支付按钮时），客户端传入参数为空!UserOrderTServiceImpl:goToPay()");
			return;
		}

		// responsebody的封装对象
		ResGoToPay resGoToPay = new ResGoToPay();

		/**
		 * 获取订单的状态
		 */
		Integer status = null;

		Userordert userordert = super.userOrderTDao.getById(goToPay.getOrderId(), false);

		// 如果订单为空，则返回系统异常
		if (userordert == null) {

			/**
			 * 修改人：冯硕楠
			 * 修改原因：订单业务新增出租车订单，所以要加上出租车订单状态的判断
			 * 修改时间：2016年7月6日19:00:04
			 * 修改版本：V2.3
			 */
			// 判断出租车订单中是否有状态
			Integer taxiStatus = super.userOrderFacade.getTaxiUserOrderStatus(goToPay.getOrderId());

			if (taxiStatus != null && taxiStatus != 0) {
				status = taxiStatus;
			} else {
				log.error("获取订单状态时，订单为空！UserOrderTServiceImpl:goToPay()");
				setStatus(dataResponse, SystemCode.ERROR);
				return;
			}
		}

		status = userordert.getOrderStatus();// 订单状态(1:待抢单 2:待支付 3:已支付
												// 4:已完成 5:已取消)
		// 如果这时候的状态不是待支付或已支付，直接返回错误
		if (status != 2 && status != 3) {
			setStatus(dataResponse, SystemCode.ERROR);
			log.error("订单不是待支付或已支付状态！UserOrderTServiceImpl:goToPay()" + "订单状态为：" + status);
			return;
		}
		resGoToPay.setOrderStatus(status); // 设置返回给客户端的订单状态

		/**
		 * 获取用户钱包信息
		 */
		ResGetUserWallet getUserWallet = super.userAccountService.getUserWalletInfo(goToPay.getUserId());// 获取用户的钱包

		if (getUserWallet == null) {
			setStatus(dataResponse, SystemCode.ERROR);
			log.error("获取用户钱包信息为空！UserOrderTServiceImpl:goToPay()");
			return;
		}

		try {
			BeanUtils.copyProperties(resGoToPay, getUserWallet);
		} catch (Exception e) {
			log.error("获取订单状态与用户钱包（点击去支付按钮时）错误！" + this.getClass().getName() + ":goToPay()", e);
			setStatus(dataResponse, SystemCode.ERROR);
		}

		// 返回成功
		dataResponse.setResponseBody(resGoToPay);
		setStatus(dataResponse, SystemCode.SUCCESS);
	}

	/**
	 * @Title: setOrderStatus
	 * @Description: 设置订单状态
	 * @param orderId 订单号
	 * @param status 订单状态
	 * @author fengshuonan
	 */
	public void setOrderStatus(String orderId, int status) {

		// 获取订单详情
		Userordert userordert = super.userOrderTDao.getById(orderId, false);

		if (userordert != null) {
			userordert.setOrderStatus(status);
		}
	}
}
